package rapier.sso.server.config.interceptor;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.util.AntPathMatcher;
import org.springframework.util.PathMatcher;
import org.springframework.web.servlet.HandlerInterceptor;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;

import rapier.sso.common.utils.ThreadLocalUtil;
import rapier.sso.core.config.redis.RedisClient;
import rapier.sso.core.entity.TDbSsoAppEntity;
import rapier.sso.core.model.ReturnModel;
import rapier.sso.server.constant.RapierComConstant;
import rapier.sso.server.constant.RapierServerConstant;
import rapier.sso.server.constant.RapierSsoBaseAppPath;
import rapier.sso.server.service.RapierAppsService;
import rapier.sso.server.utils.TokenUtils;

public class RapierAppInterceptor implements HandlerInterceptor {

	private RapierAppsService appsService;
	
	private RedisClient redisClient;

	private static final PathMatcher pathMatcher = new AntPathMatcher();

	public RapierAppInterceptor(RapierAppsService appsService,RedisClient redisClient) {
		this.appsService = appsService;
		this.redisClient = redisClient;
	}

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String servletPath = request.getServletPath();
		// 检查是否登陆
		if (pathMatcher.match(RapierSsoBaseAppPath.PATH_APP_LOGIN, servletPath)) {// 客户端登陆
			return true;// 由底层判断
		} else if (pathMatcher.match(RapierSsoBaseAppPath.PATH_APP_LOGOUT, servletPath)) {// 客户端登出
			return true;// 由底层判断
		} else if (pathMatcher.match(RapierSsoBaseAppPath.PATH_APP_REFRESH, servletPath)) {// 客户端刷新Token
			return true;// 由底层判断
		} else {// 查看Client权限
			String ticket = request.getHeader(RapierComConstant.RAPIER_COOKIE_APP_TOKEN);
			if (StringUtils.isBlank(ticket)) {
				ticket = request.getHeader(RapierComConstant.RAPIER_COOKIE_APP_REFRESH_TOKEN);
			}
			if (StringUtils.isBlank(ticket)) {
				returnJson(response, new ReturnModel<Void>(402, "客户端登陆信息已经失效!"));
				return false;
			}
			Long appId = TokenUtils.getAppId(ticket);
			Object redisTicket = redisClient.get(RapierServerConstant.REDIS_RAPIER_APP_TICKET + appId);
			if (redisTicket == null || !redisTicket.toString().equals(redisTicket)) {
				returnJson(response, new ReturnModel<Void>(402, "客户端登陆信息已经失效"));
				return false;
			}
			TDbSsoAppEntity appEntity = appsService.getAppAuthInfo(appId);
			if (!appEntity.hashAuth(servletPath)) {
				returnJson(response, new ReturnModel<Void>(403, "客户端权限不足"));
				return false;
			}
			ThreadLocalUtil.put(RapierComConstant.RAPIER_APP, appEntity);
			return true;
		}
	}

	/* 返回客户端数据 */
	private void returnJson(HttpServletResponse response, ReturnModel<Void> model) throws Exception {
		PrintWriter writer = null;
		response.setCharacterEncoding("UTF-8");
		response.setContentType("application/json;charset=utf-8");
		try {
			writer = response.getWriter();
			writer.print(JSONObject.toJSON(model));
		} catch (IOException e) {
		} finally {
			if (writer != null)
				writer.close();
		}
	}
}
